package org.anderground.app.model;

import java.io.IOException;
import java.util.Observable;

import org.anderground.app.content.AndergroundProvider;
import org.anderground.app.content.AndergroundProvider.Cities;
import org.anderground.app.storage.NoSuchCityException;
import org.anderground.app.storage.NotYetConfiguredException;
import org.anderground.app.storage.global.GlobalStorageProxy;
import org.anderground.core.Logger;
import org.anderground.core.model.ModelData;

import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;

/**
 * MVC's Model class
 * 
 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
 */
public class AppModel extends Observable {

	/** singleton instance */
	private static AppModel instance = new AppModel();

	/** the model data currently loaded in the Model */
	private ModelData modelData;

	/** city id of the currently loaded {@link #modelData} */
	private long cityId = 0;

	/**
	 * private constructor
	 */
	private AppModel() {
		modelData = new ModelData();
	}

	/**
	 * @return the instance
	 */
	public static AppModel getInstance() {
		return instance;
	}

	/**
	 * 
	 * @param context
	 * @param cityId
	 *            the city item id
	 * @return the newly loaded {@link ModelData}
	 * @throws IllegalArgumentException
	 *             if the cityId <= 0
	 */
	public ModelData load(Context context, long cityId) {
		if (cityId <= 0) {
			throw new IllegalArgumentException(cityId
					+ " must be greater than 0");
		}
		try {
			ModelData data = load(GlobalStorageProxy.getInstance().read(cityId));
			this.cityId = cityId;
			return data;
		} catch (NoSuchCityException e) {
			// TODO Auto-generated catch block
			Logger.w(e);
			return null;
		} catch (NotYetConfiguredException e) {
			// TODO Auto-generated catch block
			Logger.w(e);
			return null;
		} catch (IOException e) {
			Logger.w(e);
			return null;
		}
	}

	/**
	 * 
	 * @param context
	 * @param cityUri
	 *            the city item {@link Uri} to get id from
	 * @return the newly loaded {@link ModelData}
	 * @throws IllegalArgumentException
	 *             if the cityUri does not represent a city item
	 */
	public ModelData load(Context context, Uri cityUri) {
		if (AndergroundProvider.matchType(cityUri) != Cities.CONTENT_TYPE_ITEM) {
			throw new IllegalArgumentException(cityUri
					+ " does not represent a city item");
		}
		return load(context, ContentUris.parseId(cityUri));
	}

	/**
	 * loads a new model model
	 * 
	 * @param modelData
	 * @return the newly loaded {@link ModelData}
	 */
	public ModelData load(ModelData modelData) {
		this.modelData = modelData;
		cityId = 0;
		setChanged();
		return modelData;
	}

	/**
	 * @return the model
	 */
	public ModelData getData() {
		return modelData;
	}

	/**
	 * @return the cityId
	 */
	public long getCityId() {
		return cityId;
	}

}
